package name.tp.step;

import lombok.extern.slf4j.Slf4j;
import name.tp.modules.bom.entity.BomInfo;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.batch.MyBatisBatchItemWriter;
import org.mybatis.spring.batch.MyBatisPagingItemReader;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @author Created by Tp-wangwh on 2019-10-31.
 */
@Configuration
@Slf4j
public class BomInfoStep{

    @Resource
    private StepBuilderFactory stepBuilderFactory;  //用于构建Step
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    /**
     * 一个简单基础的Step主要分为三个部分
     * ItemReader : 用于读取数据
     * ItemProcessor : 用于处理数据
     * ItemWriter : 用于写数据
     */
    @Bean(name = "bomStep")
    public Step handleDataStep() {
        return stepBuilderFactory.get("getData").
                <BomInfo, BomInfo>chunk(500).        // <输入,输出> 。chunk通俗的讲类似于SQL的commit; 这里表示处理(processor)100条后写入(writer)一次。
                faultTolerant().retryLimit(3)
                .retry(Exception.class).skipLimit(100).skip(Exception.class). //捕捉到异常就重试,重试100次还是异常,JOB就停止并标志失败
                reader(getDataReader()).         //指定ItemReader
                processor(getDataProcessor()).   //指定ItemProcessor
                writer(getDataWriter()).         //指定ItemWriter
                build();
    }

    @Bean
    public ItemReader<? extends BomInfo> getDataReader() {
        //读取数据,这里可以用JPA,JDBC,JMS 等方式 读入数据
        MyBatisPagingItemReader<BomInfo> reader=new MyBatisPagingItemReader<>();
        // JpaPagingItemReader<Access> reader = new JpaPagingItemReader<>();
        //这里选择JPA方式读数据 一个简单的 native SQL
        try {
            reader.setQueryId("name.ealen.modules.bom.mapper.BomInfoMapper.list");
            reader.setSqlSessionFactory(sqlSessionFactory);
            reader.setPageSize(1000);
            reader.afterPropertiesSet();
            //所有ItemReader和ItemWriter实现都会在ExecutionContext提交之前将其当前状态存储在其中,如果不希望这样做,可以设置setSaveState(false)
            reader.setSaveState(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return reader;
    }

    @Bean
    public ItemProcessor<BomInfo, BomInfo> getDataProcessor() {
        return new ItemProcessor<BomInfo, BomInfo>() {
            @Override
            public BomInfo process(BomInfo bomInfo) throws Exception {
                log.info("processor data : " + bomInfo.toString());  //模拟  假装处理数据,这里处理就是打印一下
                return bomInfo;
            }
        };
//        lambda也可以写为:
//        return access -> {
//            log.info("processor data : " + access.toString());
//            return access;
//        };
    }

    @Bean
    public ItemWriter<BomInfo> getDataWriter() {
        MyBatisBatchItemWriter writer=new MyBatisBatchItemWriter();

        writer.setStatementId("name.ealen.modules.bom.mapper.BomInfoMapper.inserTestData");
        writer.setSqlSessionFactory(sqlSessionFactory);
        writer.afterPropertiesSet();
        return  writer;


    }
}
